<?php
/* SVN FILE: $Id: media_controller.php 162 2009-10-14 19:48:36Z miha@nahtigal.com $ */
/**
 * Short description for media_controller.php
 *
 * Long description for media_controller.php
 *
 * PHP versions 4 and 5
 *
 * Copyright (c) 2009, Miha Nahtigal
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @filesource
 * @copyright     Copyright (c) 2009, Miha Nahtigal
 * @link          http://www.nahtigal.com/
 * @package       lil_media_plugin
 * @subpackage    lil_media_plugin
 * @since         v 1.0
 * @version       $Revision: 162 $
 * @modifiedby    $LastChangedBy: miha@nahtigal.com $
 * @lastmodified  $Date: 2009-10-14 21:48:36 +0200 (sre, 14 okt 2009) $
 * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
 */
App::import('Controller', 'Lil.LilApp');
/**
 * MediaController class
 *
 * @uses          AppController
 * @package       lil_media_plugin
 * @subpackage    lil_media_plugin
 */
class MediaController extends LilAppController {
/**
 * index method
 *
 * @access public
 * @return int
 */
	function admin_index() {
		$root_path = $this->_rootDir();
		$base_path = DS;
		$full_path = $root_path . $base_path;
		
		if (
			!empty($this->params['named']['path']) && 
			($path = $this->_checkPath($this->params['named']['path']))
		)
		{
			$base_path = substr($path, strlen($root_path));
			$full_path = $path;
		}
		
		$www_dir = str_replace(DS, '/', substr($full_path, strlen(WWW_ROOT)-1)) . '/';
		
		// display items
		$data = array();
		if (file_exists($full_path)) {
			foreach (new DirectoryIterator($full_path) as $file_info) {
				if ($file_info->isFile()) {
					$file_data = array(
						'filename' => $file_info->getFileName(),
						'size'     => $file_info->getSize()
					);
					$data[] = $file_data;
				}
			}
		}
		
		$this->set(compact('full_path', 'base_path', 'www_dir', 'data'));
	}
/**
 * index method
 *
 * @access public
 * @return int
 */
	function admin_browse() {
		Configure::write('Lil.useAdminLayout', false);
		$this->layout = 'media_popup';
		
		$root_path = $this->_rootDir();
		$base_path = DS;
		$full_path = $root_path . $base_path;
		
		if (
			!empty($this->params['named']['path']) && 
			($path = $this->_checkPath($this->params['named']['path']))
		)
		{
			$base_path = substr($path, strlen($root_path));
			$full_path = $path;
		}
		
		$www_dir = str_replace(DS, '/', substr($full_path, strlen(WWW_ROOT) - 1));
		if (substr($www_dir, -1, 1) != '/') $www_dir .= '/';
		
		$folders = array();
		$this->_recurseFolders(
			$this->_rootDir(),
			0,
			'',
			$folders
		);
		
		// display items
		$data = array();
		foreach (new DirectoryIterator($full_path) as $file_info) {
			if ($file_info->isFile()) {
				$file_data = array(
					'filename' => $file_info->getFileName(),
					'size'     => $file_info->getSize()
				);
				$data[] = $file_data;
			}
		}
		
		$this->set(compact('full_path', 'base_path', 'data', 'folders', 'www_dir'));
	}
/**
 * _recurseFolders method
 *
 * @access private
 * @return int
 */
	function _recurseFolders($base_path, $depth, $path, &$dest) {
		foreach (new DirectoryIterator($base_path) as $file_info) {
			if ($file_info->isDot()) continue;
			if (
				$file_info->isDir() &&
				substr($file_info->getFileName(), 0, 1) !== '.' &&
				substr($file_info->getFileName(), 0, 1) !== '_'
			) {
				// add to sidebar
				$dest[uniqid()] = array(
					'name'  => $file_info->getFileName(),
					'path'  => $path . DS . $file_info->getFileName(),
					'depth' => $depth
				);
				$this->_recurseFolders(
					$base_path . DS . $file_info->getFileName(),
					$depth + 1,
					$path . DS . $file_info->getFileName(),
					$dest
				);
			}
		}
	}
/**
 * admin_view method
 *
 * @access public
 * @return int
 */
	function admin_view() {
		$root_path = $this->_rootDir();
		if (empty($this->params['named']['path']) ||
			!($path = $this->_checkPath($this->params['named']['path']))
		)
		{
			$this->error404();
		}
		
		if (empty($this->params['named']['filename']) ||
			!file_exists($path . DS . $this->params['named']['filename'])
		)
		{
			$this->error404();
		}
		$filename = $this->params['named']['filename'];
		$base_path = substr($path, strlen($root_path));
		$full_path = $root_path . $base_path;
		
		$www_dir = str_replace(DS, '/', substr($full_path, strlen(WWW_ROOT)-1)) . '/';

		$this->set(compact('filename', 'base_path', 'www_dir'));
	}
/**
 * admin_delete method
 *
 * @access public
 * @return int
 */
	function admin_delete() {
		$root_path = $this->_rootDir();
		if (empty($this->params['named']['path']) ||
			!($path = $this->_checkPath($this->params['named']['path']))
		)
		{
			$this->error404();
		}
		
		if (empty($this->params['named']['filename']) ||
			!file_exists($path . DS . $this->params['named']['filename'])
		)
		{
			$this->error404();
		}
		
		App::import('core', array('File'));
		$File = new File($path . DS . $this->params['named']['filename']);
		
		if ($File->delete())
		{
			$this->Session->setFlash(__('Your file has been successfully deleted.', true));
			$this->redirect(array(
				'plugin'     => 'lil_media',
				'admin'      => true,
				'controller' => 'media',
				'action'     => 'index',
				'path'       => (!empty($this->params['named']['path'])) ? $this->params['named']['path'] : null
			));
		} else {
			$this->Session->setFlash(__('Selected file cannot be deleted. Please try again.', true), 'error');
		}
	}
/**
 * admin_add method
 *
 * @access public
 * @return int
 */
	function admin_add() {
		if (!empty($this->data)) {
			$base_path = $this->_rootDir();
			if (!empty($this->params['named']['path'])) {
				$base_path = $this->_checkPath($this->params['named']['path']);
			}
			
			if (
				$base_path && 
				$this->Media->setBaseDir($base_path) && 
				($data = $this->Media->save($this->data))
			)
			{
				$this->Session->setFlash(__('Your files have been successfully uploaded.', true));
				$this->redirect(array(
					'plugin'     => 'lil_media',
					'admin'      => true,
					'controller' => 'media',
					'action'     => 'index',
					'path'       => (!empty($this->params['named']['path'])) ? 
									$this->params['named']['path'] : null
				));
			} else {
				$this->Session->setFlash(__('There are some errors in the form. Please correct all marked fields below.', true), 'error');
			}
		}
	}
/**
 * admin_mk_dir method
 *
 * @access public
 * @return int
 */
	function admin_mk_dir() {
		if (!empty($this->data['Media']['folder'])) {
			$base_path = $this->_rootDir();
			
			if (!empty($this->params['named']['path'])) {
				$path = $this->_checkPath($this->params['named']['path']);
			} else {
				$path = $base_path;
			}
			
			App::import('core', array('Folder', 'Sanitize'));
			
			$Folder = new Folder();
			$folder_name = Sanitize::paranoid($this->data['Media']['folder'], array('_', '-'));
			
			if (
				$path && 
				!file_exists($path . DS . $folder_name) &&
				$Folder->create($path . DS . $folder_name)
			)
			{
				$return_path = base64_encode(substr($path . DS . $folder_name, strlen($base_path)));
				
				$this->Session->setFlash(__('Your folder has been successfully created.', true));
				$this->redirect(array(
					'plugin'     => 'lil_media',
					'admin'      => true,
					'controller' => 'media',
					'action'     => 'index',
					'path'       =>(!empty($return_path)) ? $return_path : null
				));
			} else {
				$this->Session->setFlash(__('There are some errors in the form. Please correct all marked fields below.', true), 'error');
			}
		}
	}
/**
 * admin_mk_dir method
 *
 * @access public
 * @return int
 */
	function admin_rm_dir() {
		if (!empty($this->params['named']['path'])) {
			$base_path = $this->_rootDir();
			$path = $this->_checkPath($this->params['named']['path']);
			
			App::import('core', array('Folder'));
			$Folder = new Folder();
			
			if (
				$path && 
				realpath($base_path) != $path &&
				file_exists($path) &&
				$Folder->delete($path)
			)
			{
				$return_path = base64_encode(substr(dirname($path), strlen($base_path)));
				
				$this->Session->setFlash(__('Your folder has been successfully deleted.', true));
				$this->redirect(array(
					'plugin'     => 'lil_media',
					'admin'      => true,
					'controller' => 'media',
					'action'     => 'index',
					'path'       => (!empty($return_path)) ? $return_path : null
				));
			} else {
				$this->Session->setFlash(__('Selected folder cannot be deleted. Please try again.', true), 'error');
			}
		}
	}
/**
 * _checkPath method
 *
 * This function checks if given path is within allowed $base_path
 *
 * @access private
 * @return int
 */
	function _checkPath($path) {
		$base_path = $this->_rootDir();
		if ($decoded_path = base64_decode($this->params['named']['path'])) {
			if ($real_path = realpath($base_path . $decoded_path)) {
				if (substr($real_path, 0, strlen($base_path)) !== $base_path) {
					return false;
				} else {
					return $real_path;
				}
			} else {
				$this->error404();
				return;
			}
		}
		return false;
	}
/**
 * _rootDir method
 *
 * Returns root dir
 *
 * @access private
 * @return int
 */
	function _rootDir() {
		$blog = $this->getAdminBlog();
		return Configure::read('LilMedia.baseDir') . $blog['Blog']['slug'];
	}
}
?>